package jbrowser.gui.history;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class HistoryManager implements PopupMenuListener, ActionListener {

    private JComboBox comboBox;
    private JButton backButton;
    private JButton nextButton;
    private JPopupMenu backPopupMenu;
    private JPopupMenu nextPopupMenu;
    private History<URI> history;

    public static void manage(History<URI> history, JComboBox comboBox, JButton backButton, JButton nextButton) {
        HistoryManager manager = new HistoryManager();
        manager.history = history;
        manager.comboBox = comboBox;
        //
        manager.comboBox.addActionListener(manager);
        //
        manager.backButton = backButton;
        manager.backPopupMenu = new JPopupMenu();
        manager.backPopupMenu.addPopupMenuListener(manager);
        backButton.addActionListener(manager);
        backButton.setComponentPopupMenu(manager.backPopupMenu);
        //
        manager.nextButton = nextButton;
        manager.nextPopupMenu = new JPopupMenu();
        manager.nextPopupMenu.addPopupMenuListener(manager);
        nextButton.addActionListener(manager);
        nextButton.setComponentPopupMenu(manager.nextPopupMenu);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(comboBox)) {
            history.add(URI.create(comboBox.getSelectedItem().toString()));
        }
        if (e.getSource().equals(backButton)) {
            if (history.hasBack()) {
                comboBox.getEditor().setItem(history.back());
            }
        } else if (e.getSource().equals(nextButton)) {
            if (history.hasNext()) {
                comboBox.getEditor().setItem(history.next());
            }
        } else if (e.getSource() instanceof JMenuItem) {
            JMenuItem menuItem = (JMenuItem) e.getSource();
            URI uri = (URI) menuItem.getClientProperty("URI");
            int jumpIndex = history.indexOf(uri);
            history.jump(jumpIndex);
            comboBox.setSelectedItem(uri);
        }
        comboBox.removeActionListener(this);
        comboBox.actionPerformed(null);
        comboBox.addActionListener(this);
        backButton.setEnabled(history.hasBack());
        nextButton.setEnabled(history.hasNext());
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        JPopupMenu popupMenu = (JPopupMenu) e.getSource();
        if (popupMenu.equals(backPopupMenu)) {
            backPopupMenu.removeAll();
            if (history.hasBack()) {
                for (URI uri : history.getAvailableBackHistory()) {
                    JMenuItem menuItem = new JMenuItem(uri.toString());
                    menuItem.addActionListener(this);
                    menuItem.putClientProperty("URI", uri);
                    backPopupMenu.add(menuItem, 0);
                }
            }
        } else if (popupMenu.equals(nextPopupMenu)) {
            nextPopupMenu.removeAll();
            if (history.hasNext()) {
                for (URI uri : history.getAvailableNextHistory()) {
                    JMenuItem menuItem = new JMenuItem(uri.toString());
                    menuItem.addActionListener(this);
                    menuItem.putClientProperty("URI", uri);
                    nextPopupMenu.add(menuItem);
                }
            }
        } else {
            throw new IllegalArgumentException();
        }
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    }

    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {
    }
}
